;; The first four lines of this file were added by Dracula.
;; They tell DrScheme that this is a Dracula Modular ACL2 program.
;; Leave these lines unchanged so that DrScheme can properly load this file.
#reader(planet "reader.rkt" ("cce" "dracula.plt") "modular" "lang")
(require "igreyscale.lisp")
(require "mbmptree.lisp")

(module mGreyscale
  (import iBmpTree)
  
  ; Convert one pixel's RGB values to greyscale
  ; pre: r - red [0, 255]
  ;      g - green [0, 255]
  ;      b - blue [0, 255]
  ;    col - column
  ; post: list containing the column number and
  ;       new red, green, blue values in greyscale
  (defun pixel-to-greyscale (col r g b)
    (if (and (<= r 255) (>= r 0)
             (<= g 255) (>= g 0)
             (<= b 255) (>= b 0))
        (let* ((maximum (max (max r g) b))
               (minimum (min (min r g) b ))
               (grey (floor (+ maximum minimum) 2)))
          (list col grey grey grey))
        "Invalid RGB value."))
 
  ; Converts each value in a row to greyscale
  ; pre: row - list of column values of a row from the bitmap tree
  ;  columns - list of modified columns values to be returned
  ; post: list containing the each modified column in the row
  ;       where a column is a list of the column number and its
  ;       new red, green, blue values in greyscale
  (defun make-greyscale-columns (row columns)
    (if (consp row)
        (let* ((col    (car row))
               (colNum (car col))
               (r      (cadr col))
               (g      (caddr col))
               (b      (cadddr col)))
          (make-greyscale-columns (cdr row) (cons (pixel-to-greyscale colNum r g b) columns)))
        columns))
  
  ; Converts the given tree to greyscale.
  ; pre:    tr - bitmap tree
  ;   rowIndex - current row index, used for looping
  ;    numRows - total number of rows in the tree
  ; post: tree containing greyscale values
  (defun greyscale-helper (tr rowIndex numRows)
    (if (< rowIndex numRows)
        (let* ((row (get-row tr rowIndex)))
          (greyscale-helper (insert-row tr rowIndex (make-greyscale-columns row nil))
                            (+ rowIndex 1) numRows))
        tr))
  
  ; Converts the given tree to greyscale using the greyscale-helper function.
  ; pre: tr - bitmap tree
  ; post: tree containing greyscale values
  (defun greyscale (tr)
    (let* ((numRows (car (get-dimensions tr))))
      (greyscale-helper tr 0 numRows)))
  
  (export iGreyscale))